package nl.ru.rd.facedetection.nnbfd.tests;

import nl.ru.rd.facedetection.nnbfd.neuralnetwork.Activationfunction;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.BMLayer;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.BNLayer;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.Input;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.InputLayer;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.Layer;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.NeuralNetwork;
import nl.ru.rd.facedetection.nnbfd.neuralnetwork.SigmoidActivationfunction;

/**
 * A Complex Network utilizing a backpropagatable metalayer. Has two input layers with two inputs each, with each a hidden layer of two nodes, a joining
 * metalayer of four nodes and a final outputlayer of one node.
 * 
 * @author Wouter Geraedts (s0814857)
 */
public class ComplexNetwork extends NeuralNetwork
{
	public ComplexNetwork()
	{
		super();
		this.initialize();
	}

	private void initialize()
	{
		InputLayer inputLayer1 = new InputLayer();
		for(int i = 0; i < 2; i++)
		{
			Input input = new Input(0.0);
			this.registerInput(input);
			inputLayer1.addInput(input);
		}
		this.registerLayer(inputLayer1);

		InputLayer inputLayer2 = new InputLayer();
		for(int i = 0; i < 2; i++)
		{
			Input input = new Input(0.0);
			this.registerInput(input);
			inputLayer2.addInput(input);
		}
		this.registerLayer(inputLayer2);

		Activationfunction f = new SigmoidActivationfunction();
		BNLayer hiddenLayer1 = new BNLayer(inputLayer1, 2, f);
		this.registerLayer(hiddenLayer1);
		BNLayer hiddenLayer2 = new BNLayer(inputLayer2, 2, f);
		this.registerLayer(hiddenLayer2);

		BMLayer couplingLayer = new BMLayer(new Layer[] { hiddenLayer1, hiddenLayer2 }, 4, f);
		this.registerLayer(couplingLayer);

		BNLayer outputLayer = new BNLayer(couplingLayer, 1, f);
		this.registerLayer(outputLayer);
		this.registerOutputLayer(outputLayer);
	}
}
